function sub(a, b) {
  console.log(arguments)
  console.log(this)
  return a + b
}

const foo = {}

// const result = sub.apply(null,[1,2])
// const result = sub.call(foo,1,2)
// console.log(result)
// const result = sub.bind(foo,1,2)()
// console.log(result)

Function.prototype.myApply = function (thisArg, argArray = []) {
  //防止传null
  thisArg = thisArg || globalThis
  //保证key的唯一性
  const fn = Symbol()
  //将原函数保存到给到的对象的fn属性上
  thisArg[fn] = this
  //改变this 调用原函数
  const result = thisArg[fn](...argArray)
  //还原对象
  Reflect.deleteProperty(thisArg, fn)
  return result
}


Function.prototype.myCall = function (thisArg, ...arg) {
  thisArg = thisArg || globalThis
  const fn = Symbol()
  thisArg[fn] = this
  const result = thisArg[fn](...arg)
  Reflect.deleteProperty(thisArg, fn)
  return result
}


Function.prototype.myBind = function (thisArg, ...arg) {
  return (...args) => {
    return this.myCall(thisArg, ...arg, ...args)
  }
}
// const result = sub.myApply(null,[1,2])
// console.log(result)

// const result = sub.myCall(foo,1,2)
// console.log(result,foo)

// const fn = sub.myBind(foo,1,2)
// console.log(fn(1,3))
